home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / music4c.sit / Music4C Folder / Sources Folder / AIFFHeader.c < prev    next >
Text File  |  1990-06-08  |  8KB  |  260 lines

  1. /*
  2. * ⌐ Graeme Gerrard 1990
  3. * Faculty of Music, University of Melbourne
  4. * Parkville Victoria 3052 Australia.
  5. *
  6. * ARPANET: grae@murdu.ucs.unimelb.edu.au
  7. * telephone: (613) 344 4127, Fax: (613) 344 5346
  8. */
  9. #include    "Music4C.h"
  10. #include    <unix.h>
  11. #include    <SANE.h>
  12. #include    "AIFFtype.h"
  13. #include    "Music4C_Prototype.h"
  14. #include    "ErrorAlert.h"
  15.  
  16. extern    OSErr    theErr;
  17. void            prepareAIFFfile(double, int);
  18. void    FixHeaderInfo(void);
  19.  
  20.  
  21.  
  22. void    prepareAIFFfile(TotalDuration, nchnls)
  23.     double    TotalDuration;
  24.     int    nchnls;
  25. {
  26.     register    i;
  27.     double    x;
  28.     Str255    myStr255;
  29.     long    aLong;
  30.     extern    double    srate;
  31.     int    resid;
  32.     Chunk            FormChunkHeader, *FormChunkHeaderPtr;
  33.     CommonChunk        CommonHeader, *CommonHeaderPtr;
  34.     SoundDataChunk    SoundDataHeader, *SoundDataHeaderPtr;
  35.     MarkerChunk        MarkerChunkHeader, *MarkerChunkHeaderPtr;
  36.     InstrumentChunk        InstHeader, *InstHeaderPtr;
  37.     long            TotalSamps;
  38.     extern            Boolean            AIFFoddByte;
  39.     extern            double        srate;        /* sampling rate */
  40.     extern            Str255        SoundFileName;
  41.     extern            ioParam        myIOParmBlk;
  42.     extern        long            SampleRate;
  43.     extern        Str255            theMess1;
  44.  
  45.     FormChunkHeaderPtr = &FormChunkHeader;
  46.     CommonHeaderPtr = &CommonHeader;
  47.     SoundDataHeaderPtr = &SoundDataHeader;
  48.     aLong =  (long)(TotalDuration * nchnls * srate);
  49.     resid =  (int)(aLong % 512L);
  50.     if ( resid != 0 ) {
  51.         aLong += (long)(512 - resid) + 512L;;
  52.     }
  53.     TotalSamps = aLong;
  54.  
  55. /* initialize Form Chunk info */
  56.     FormChunkHeader.ckID = 'FORM';
  57.     FormChunkHeader.formType = 'AIFF';
  58.  
  59.  
  60. /* initialize Common Chunk info */
  61.     CommonHeader.ckID = 'COMM';
  62.     CommonHeader.ckSize = sizeof( CommonHeader.numChannels ) +
  63.                             sizeof( CommonHeader.numSampleFrames ) +
  64.                             sizeof( CommonHeader.sampleSize ) +
  65.                             sizeof( CommonHeader.sampleRate );
  66.     CommonHeader.numChannels = (short)nchnls;
  67.     CommonHeader.numSampleFrames = (unsigned long)(TotalSamps / nchnls);
  68.     CommonHeader.sampleSize = SixteenBits;
  69.  
  70.     SampleRate = (long)srate;
  71.     NumToString(SampleRate, &myStr255);
  72.     CommonHeader.sampleRate = str2num(&myStr255);    /* string to extended */
  73.     
  74.  
  75.     SoundDataHeader.ckID = 'SSND';
  76.     SoundDataHeader.offset = 0L;
  77.     SoundDataHeader.blockSize = 0L;
  78.  
  79.     SoundDataHeader.ckSize = sizeof( SoundDataHeader.offset ) +
  80.                                 sizeof( SoundDataHeader.blockSize ) +
  81.                                 (long)(TotalSamps * sizeof(int));
  82.                                 
  83.                                 
  84.                                 
  85.     FormChunkHeader.ckSize = sizeof(FormChunkHeader.formType);
  86.     
  87.     FormChunkHeader.ckSize += (sizeof(CommonHeader.ckID) + 
  88.                             sizeof(CommonHeader.ckSize)
  89.                                 + CommonHeader.ckSize);
  90.                                 
  91.     FormChunkHeader.ckSize += (sizeof(SoundDataHeader.ckID) + 
  92.                                 sizeof(SoundDataHeader.ckSize)
  93.                                 + SoundDataHeader.ckSize);
  94.                                 
  95.     if ( FormChunkHeader.ckSize % 2 != 0 )
  96.         AIFFoddByte = TRUE;
  97.     else
  98.         AIFFoddByte = FALSE;
  99.  
  100.                                 
  101. /* write out header info */
  102.     myIOParmBlk.ioReqCount = sizeof(FormChunkHeader);
  103.     myIOParmBlk.ioBuffer = (Ptr)FormChunkHeaderPtr;
  104.     if ( (theErr = PBWrite(&myIOParmBlk, FALSE)) != noErr ) { 
  105.         PstringCopy((char *)theMess1, "\pError writing Header to sample file");
  106.         OSError(theMess1, NIL, NIL);
  107.  
  108.     }
  109.     if ( myIOParmBlk.ioActCount != myIOParmBlk.ioReqCount) {
  110.         PstringCopy((char *)theMess1, "\pError writing Header to file, wrote wrong number of bytes");
  111.         OSError(theMess1, NIL, NIL);
  112.     }
  113.  
  114.     myIOParmBlk.ioReqCount = sizeof(CommonHeader);
  115.     myIOParmBlk.ioBuffer = (Ptr)CommonHeaderPtr;
  116.     if ( (theErr = PBWrite(&myIOParmBlk, FALSE)) != noErr ) { 
  117.         PstringCopy((char *)theMess1, "\pError writing Header to sample file");
  118.         OSError(theMess1, NIL, NIL);
  119.     }
  120.     if ( myIOParmBlk.ioActCount != myIOParmBlk.ioReqCount) {
  121.         PstringCopy((char *)theMess1, "\pError writing Header to file, wrote wrong number of bytes");
  122.         OSError(theMess1, NIL, NIL);
  123.     }
  124.  
  125.     myIOParmBlk.ioReqCount = sizeof(SoundDataHeader);
  126.     myIOParmBlk.ioBuffer = (Ptr)SoundDataHeaderPtr;
  127.     if ( (theErr = PBWrite(&myIOParmBlk, FALSE)) != noErr ) { 
  128.         PstringCopy((char *)theMess1, "\pError writing Header to file");
  129.         OSError(theMess1, NIL, NIL);
  130.     }
  131.     if ( myIOParmBlk.ioActCount != myIOParmBlk.ioReqCount) {
  132.         PstringCopy((char *)theMess1, "\pError writing Header to file, wrote wrong number of bytes");
  133.         OSError(theMess1, NIL, NIL);
  134.     }
  135. }
  136.  
  137.  
  138. void    FixHeaderInfo()
  139. {
  140. /* this is a kludgey way to ensure that the AIFF file header
  141. * info is accurate. We just read it all back again from the file
  142. * and patch it up.
  143. */
  144.  
  145.     register    i;
  146.     Str255    myStr255;
  147.     double    x;
  148.     extern        double        srate;
  149.     long    aLong;
  150.     int    resid;
  151.     Chunk            FormChunkHeader, *FormChunkHeaderPtr;
  152.     CommonChunk        CommonHeader, *CommonHeaderPtr;
  153.     SoundDataChunk    SoundDataHeader, *SoundDataHeaderPtr;
  154.     MarkerChunk        MarkerChunkHeader, *MarkerChunkHeaderPtr;
  155.     InstrumentChunk        InstHeader, *InstHeaderPtr;
  156.     extern            long        TotalSamps;
  157.     extern            Boolean        AIFFoddByte;
  158.     extern            double        srate;        /* sampling rate */
  159.     extern            Str255        SoundFileName;
  160.     extern            ioParam        myIOParmBlk;
  161.     extern            int            nchnls;
  162.  
  163.     FormChunkHeaderPtr = &FormChunkHeader;
  164.     CommonHeaderPtr = &CommonHeader;
  165.     SoundDataHeaderPtr = &SoundDataHeader;
  166.  
  167.  
  168. /* reset file position to start */
  169.  
  170.     myIOParmBlk.ioPosMode = fsFromStart;
  171.     myIOParmBlk.ioPosOffset = 0L;
  172.     theErr = PBSetFPos(&myIOParmBlk, FALSE);
  173.     myIOParmBlk.ioPosMode = fsAtMark;
  174.  
  175.  
  176.  
  177.  
  178. /* initialize Form Chunk info */
  179.     FormChunkHeader.ckID = 'FORM';
  180.     FormChunkHeader.formType = 'AIFF';
  181.  
  182.  
  183. /* initialize Common Chunk info */
  184.     CommonHeader.ckID = 'COMM';
  185.     CommonHeader.ckSize = sizeof( CommonHeader.numChannels ) +
  186.                             sizeof( CommonHeader.numSampleFrames ) +
  187.                             sizeof( CommonHeader.sampleSize ) +
  188.                             sizeof( CommonHeader.sampleRate );
  189.     CommonHeader.numChannels = (short)nchnls;
  190.     CommonHeader.numSampleFrames = (unsigned long)(TotalSamps / nchnls);
  191.     CommonHeader.sampleSize = SixteenBits;
  192.  
  193.  
  194.     SampleRate = (long)srate;
  195.     NumToString(SampleRate, &myStr255);
  196.     CommonHeader.sampleRate = str2num(&myStr255);    /* string to extended */
  197.  
  198.     
  199.  
  200.     SoundDataHeader.ckID = 'SSND';
  201.     SoundDataHeader.offset = 0L;
  202.     SoundDataHeader.blockSize = 0L;
  203.  
  204.     SoundDataHeader.ckSize = sizeof( SoundDataHeader.offset ) +
  205.                                 sizeof( SoundDataHeader.blockSize ) +
  206.                                 (long)(TotalSamps * sizeof(int));
  207.                                 
  208.                                 
  209.                                 
  210.     FormChunkHeader.ckSize = sizeof(FormChunkHeader.formType);
  211.     
  212.     FormChunkHeader.ckSize += (sizeof(CommonHeader.ckID) + 
  213.                             sizeof(CommonHeader.ckSize)
  214.                                 + CommonHeader.ckSize);
  215.                                 
  216.     FormChunkHeader.ckSize += (sizeof(SoundDataHeader.ckID) + 
  217.                                 sizeof(SoundDataHeader.ckSize)
  218.                                 + SoundDataHeader.ckSize);
  219.                                 
  220.     if ( FormChunkHeader.ckSize % 2 != 0 )
  221.         AIFFoddByte = TRUE;
  222.     else
  223.         AIFFoddByte = FALSE;
  224.  
  225.                                 
  226. /* REwrite out header info */
  227.     myIOParmBlk.ioReqCount = sizeof(FormChunkHeader);
  228.     myIOParmBlk.ioBuffer = (Ptr)FormChunkHeaderPtr;
  229.     if ( (theErr = PBWrite(&myIOParmBlk, FALSE)) != noErr ) { 
  230.         PstringCopy((char *)theMess1, "\pError writing Header to sample file");
  231.         OSError(theMess1, NIL, NIL);
  232.     }
  233.     if ( myIOParmBlk.ioActCount != myIOParmBlk.ioReqCount) {
  234.         PstringCopy((char *)theMess1, "\pError writing Header to file, wrote wrong number of bytes");
  235.         OSError(theMess1, NIL, NIL);
  236.     }
  237.  
  238.     myIOParmBlk.ioReqCount = sizeof(CommonHeader);
  239.     myIOParmBlk.ioBuffer = (Ptr)CommonHeaderPtr;
  240.     if ( (theErr = PBWrite(&myIOParmBlk, FALSE)) != noErr ) { 
  241.         PstringCopy((char *)theMess1, "\pError writing Header to sample file");
  242.         OSError(theMess1, NIL, NIL);
  243.     }
  244.     if ( myIOParmBlk.ioActCount != myIOParmBlk.ioReqCount) {
  245.         PstringCopy((char *)theMess1, "\pError writing Header to file, wrote wrong number of bytes");
  246.         OSError(theMess1, NIL, NIL);
  247.     }
  248.  
  249.     myIOParmBlk.ioReqCount = sizeof(SoundDataHeader);
  250.     myIOParmBlk.ioBuffer = (Ptr)SoundDataHeaderPtr;
  251.     if ( (theErr = PBWrite(&myIOParmBlk, FALSE)) != noErr ) { 
  252.         PstringCopy((char *)theMess1, "\pError writing Header to sample file");
  253.         OSError(theMess1, NIL, NIL);
  254.     }
  255.     if ( myIOParmBlk.ioActCount != myIOParmBlk.ioReqCount) {
  256.         PstringCopy((char *)theMess1, "\pError writing Header to file, wrote wrong number of bytes");
  257.         OSError(theMess1, NIL, NIL);
  258.     }
  259. }
  260.